package org.harsh.transmission.common;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bouncycastle.util.Arrays;
import org.harsh.common.Constants;
import org.harsh.common.Util;

import java.io.IOException;
import java.nio.ByteBuffer;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CustomMsg implements ITransable {
    // 消息类型 Constants.MessageType
    private byte msgType;
    // 传输类型 0 - 单播 1 - 组播 2 - 广播 3 - 单向
    private byte transType;
    // 数据编号
    private long msgId;
    // 节点编号
    private int fromNode;
    // 数据来源 0 - 用户 1 - 业务系统
    private byte fromType;
    // 数据来源ID
    private int fromId;
    // 接收用户信息
    private int recvId;
    // 16字节
    private byte[] msgMd5;
    private byte[] msgData;

    /**
     * AckTransMsg
     */
    public CustomMsg(byte msgType, long msgId, byte[] data) throws IOException {
        this.msgType = msgType;
        this.msgId = msgId;
        this.msgMd5 = Util.byteArrMD5(data);
        this.msgData = data;
    }

    public void parseTransMsg(byte msgType, byte[] data){
        this.setMsgType(msgType);
        this.setTransType(data[0]);
        this.setMsgId(Util.bytes2Long(data, 1));
        this.setFromNode(Util.bytes2int(data, 9));
        this.setFromType(data[13]);
        this.setFromId(Util.bytes2int(data,14));
        this.setRecvId(Util.bytes2int(data,18));
        this.setMsgMd5(Arrays.copyOfRange(data, 22, 38));
        this.setMsgData(Arrays.copyOfRange(data, 38, data.length));
    }

    public void parseTransAckMsg(byte msgType, byte[] data) {
        this.setMsgType(msgType);
        this.setTransType(data[0]);
        this.setMsgId(Util.bytes2Long(data, 1));
        this.setMsgMd5(Arrays.copyOfRange(data, 9, 25));
        this.setMsgData(Arrays.copyOfRange(data, 26, data.length));
    }

    /**
     * 转换为byte arr
     * @return
     */
    public byte[] buildBytes() {
        if(msgType == Constants.MessageType.ACKTRANSMSG.getCode()) {
            // 消息响应
            ByteBuffer buf = ByteBuffer.allocate(26);
            buf.put(msgType).put(transType).putLong(msgId).put(msgMd5);
            return Arrays.concatenate(buf.array(), msgData);
        } else if(msgType == Constants.MessageType.TRANSMSG.getCode()) {
            ByteBuffer buf = ByteBuffer.allocate(39);
            buf.put(msgType).put(transType).putLong(msgId).putInt(fromNode)
                    .put(fromType).putInt(fromId).putInt(recvId)
                    .put(msgMd5);
            return Arrays.concatenate(buf.array(), msgData);
        } else {
            return null;
        }
    }
}
